home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / tas412.zip / DMI.TAS < prev    next >
Text File  |  1991-09-01  |  7KB  |  203 lines

  1. #MAX_QUOTES 150
  2. #OUTPUT_FILE 'DMI.LST+'
  3. { DMI.TAS :
  4.    Script to implement Wilder's Directional Movement Trading
  5.    System.
  6.    Source : "DMI Trading Rules",Jim Summers,
  7.     Technical Analysis of Stocks and Commodities, Dec 1988
  8.     and "New Concepts in Technical Trading Systems", Wilder
  9.     --------------------Rules----------------------------
  10.     Enter Position if all of the following are true:
  11.         1) +DI and -DI cross
  12.            if +DI > -DI enter LONG
  13.            if +DI < -DI enter SHORT
  14.         2) ADXR > 25
  15.         3) ADX not below both +DI and -DI
  16.         4) ADX not above both +DI and -DI
  17.         Set Extreme Point on entry to position as follows:
  18.             if LONG,  Extreme Point is LOW
  19.             if SHORT, Extreme Point is HIGH
  20.     Exit Position and either of the following:
  21.         1) ADX above both DI lines and then turns down
  22.         2) If DI lines cross against entry position AND
  23.            HIGH > Extreme Point (SHORT) or
  24.            LOW  < Extreme Point (LONG)
  25.   ------------SCRIPT IMPLEMENTATION DETAILS-------------
  26.    This script is somewhat complex, because Wilder's system
  27.    itself is complex. We are starting at the "current"
  28.    day, in each ticker file. If the entry conditions are
  29.    true, we put out a message indicating which position
  30.    we should take.
  31.    If, on the other hand, either of the Exit conditions are
  32.    true, the script does something you probably haven't
  33.    seen before. Imagine the ticker data is displayed on a
  34.    price bar chart. Using the pre-defined variable
  35.    "QUOTE_RANGE", it "slides" the "right" edge to the
  36.    left, one day at a time, until it finds an Entry
  37.    condition as shown in rules 1-4 of the Entry rules (above).
  38.    Each day is checked using a "subroutine" implemented using 
  39.    GOSUB to the CHECKRULES routine. 
  40.    This version works with TAS 3.62 or later only.
  41. }
  42. pdi_a : array;    { +DI array }
  43. mdi_a : array;    { -DI array }
  44. adx_a : array;    { ADX array }
  45. adxr_a : array;    { ADXR array }
  46. avg_adx : number;   { Average ADX value across all tickers}
  47. buy_signal : number;
  48. sell_signal : number;
  49. dmi_days = 14;    { Number of days in ADX and DI calculations }
  50. ADXR_limit = 20;   { lower limit for ADX }
  51. i     : number;   { Index for backing up in time }
  52. j     : number;   { Another index for backing up in time }
  53. rule1 : number;   { +/-DI crossing}
  54. rule2 : number;   { ADX >= 20}
  55. rule3 : number;   { ADX not below both +/-DI}
  56. rule4 : number;   { ADX not above both +/-DI}
  57. postype : number; { Position type LONG(+1), SHORT(-1) none(0)}
  58. opostype : number; {Open position type}
  59. epostype : number; {Exit position type}
  60. extreme_point : number;   { Extreme Point Rule value}
  61. oextreme_point : number;   { Open Extreme Point Rule value}
  62. warning : number;
  63. if first_ticker then
  64. begin
  65. writeln(
  66. '--------------------------------------------------------------');
  67. writeln(
  68. 'Signals based on Welles Wilders Directional Movement System');
  69. writeln(
  70. ' ');
  71. writeln(
  72. 'Action       Description  ');
  73. writeln(
  74. '------       --------------------------------------------------');
  75. writeln(
  76. 'Open         ADXR > 25, +DI crossed -DI, and ADX between +/-DI');
  77. writeln(
  78. 'Exit (ExP)   +DI crossed -DI and Extreme Point violated');
  79. writeln(
  80. 'Exit (ADX)   ADX above +DI and -DI and turned down');
  81. writeln(
  82. 'Warning      +DI and -DI crossed, but Extreme Point not ');
  83. writeln(
  84. '             violated');
  85. writeln(
  86. '--------------------------------------------------------------');
  87. writeln(
  88. '                          EXTREME  CURRENT      OPEN');
  89. writeln(
  90. 'TICKER  ACTION  POSITION    POINT    CLOSE      DATE');
  91. end;
  92. if quote_count < dmi_days * 3 then return;
  93. ticker_count = ticker_count + 1;
  94. pdi_a = pdi(dmi_days);
  95. mdi_a = mdi(dmi_days);
  96. adx_a = adx(dmi_days);
  97. adxr_a = adxr(dmi_days);
  98. postype = 0;
  99. warning = 0;
  100. opostype = 0;
  101. epostype = 0;
  102. j = quote_range;        { short name for index back in time}
  103. { check if adx has turned down}
  104. if adx_a > pdi_a and adx_a > mdi_a and
  105.     adx_a[0] < adx_a[-1] and adx_a[-1] > adx_a[-2] then begin
  106.     epostype = 2;
  107.     end;
  108. if epostype = 2 then   { adx turned down..see if we had open pos}
  109.     goto BACKCHECK;
  110. GOSUB CHECKRULES;
  111. :RETURN1                { this is where CHECKRULES returns if
  112.                           switch = 1}
  113. opostype = postype;
  114. oposition = position;
  115. oextreme_point = extreme_point;
  116. postype = 0;
  117. { Not entering a position..see if we should exit a prior one }
  118. IF rule1 = 0 THEN GOTO TICKDONE;  { DI lines did not cross today }
  119. { DI lines crossed..see if this is the time to exit a prior position}
  120. i = 1;
  121. :BACKCHECK
  122. quote_range = quote_count - i;  { lower top of array }
  123. j = quote_range;        { short name for index back in time}
  124. {Stop when we have less than twice the DMI period days left}
  125. if quote_range <= dmi_days * 2 then goto NOPRIOR;
  126. if isect(pdi_a,mdi_a) < 0 then goto NOPRIOR;
  127. GOSUB CHECKRULES;
  128. :RETURN2
  129. if postype <> 0 then GOTO EXITRULE;
  130. i = i + 1;
  131. GOTO BACKCHECK;
  132. :EXITRULE
  133. { we have found entry position }
  134. quote_range = quote_count;  { reset quote range back to present}
  135. if epostype = 2 then    { exit because of adx turning down}
  136.     goto TICKDONE;
  137. if postype = -1 then
  138.     if extreme_point < H then
  139.         epostype = postype
  140.     else
  141.         warning = 1;
  142. if postype = 1 then
  143.     if extreme_point > L then
  144.         epostype = postype;
  145.     else
  146.         warning = 1;
  147. :NOPRIOR
  148. GOTO TICKDONE;
  149. { This is a "subroutine" to check if a position should be entered.
  150.   It sets variable "position" to either LONG or SHORT if so}
  151. :CHECKRULES
  152. position = '     ';
  153. postype = 0;
  154. rule1 = isect(pdi_a,mdi_a) = 0; { if +DI intersected -DI today}
  155. rule2 = adxr_a[j] > ADXR_limit;
  156. rule3 = adx_a[j] >= pdi_a[j] OR adx_a[j] >= mdi_a[j];
  157. rule4 = adx_a[j] <= pdi_a[j] OR adx_a[j] <= mdi_a[j];
  158. IF rule1 AND rule2 AND rule3 AND rule4 THEN
  159. BEGIN
  160.     IF pdi_a[j] > mdi_a[j] THEN
  161.     BEGIN
  162.         position = 'LONG ';
  163.         postype  = 1;
  164.         extreme_point = l[j];      { if long, extreme point is low}
  165.     END
  166.     ELSE
  167.     BEGIN
  168.         position = 'SHORT';
  169.         postype  = -1;
  170.         extreme_point = h[j];      { if short, extreme point is high}
  171.     END;
  172. END;
  173. RETURN;        { to caller of CHECKRULES}
  174. :TICKDONE
  175. if warning <> 0 then    { If giving a warning, don't open position}
  176.     opostype = 0;
  177. if warning = 1 then
  178. writeln(TICKER,'Warning    ',position ,' ',extreme_point,' ',C,
  179.     '  ',datestr(dates[j]));
  180. if epostype <> 0 then
  181.     if epostype = 2 then
  182.         if postype <> 0 then
  183.         begin
  184.             emsg = 'Exit (ADX) '
  185.             eposition = position;
  186.             epostype = postype;
  187.         end
  188.         else
  189.             epostype = 0
  190.     else
  191.         emsg = 'Exit (ExP) ';
  192. if epostype <> 0 then
  193. writeln(TICKER,emsg,position ,' ',extreme_point ,' ',C,
  194.     '  ',DATESTR(DATES[j]));
  195. if opostype <> 0 then
  196. writeln(TICKER,'Open       ',oposition,' ',oextreme_point,' ',C,
  197.     '  ',DATE);
  198. avg_adx = avg_adx + adx_a;
  199. IF last_ticker then
  200. BEGIN
  201.     writeln('Average ADX is ',avg_adx/ticker_count);
  202. END;
  203.